home *** CD-ROM | disk | FTP | other *** search
- // --------------------------------------------------------------------------
- //
- // File: MAP.C
- // Author: Sulyok Peter (C) 1992,1994.
- // Compiler: Borland C++ 3.1 (COMPACT model with byte alignment)
- // Notes: Memory map.
- //
- // --------------------------------------------------------------------------
-
- // Include files ------------------------------------------------------------
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <mem.h>
- #include <string.h>
-
- // Constants ----------------------------------------------------------------
- #define uchar unsigned char
- #define ushort unsigned int
- #define ulong unsigned long
-
- #define FALSE 0
- #define TRUE 1
-
- #define MAX_ITEM 150
- #define MAX_VEC 100
- #define MAX_DRIVE 20
- #define MAX_HANDLE 255
-
- #define MT_NONE 0
- #define MT_SYSCODE 1
- #define MT_SYSDATA 2
- #define MT_PROGRAM 3
- #define MT_DEVICE 4
- #define MT_ENV 5
- #define MT_DATA 6
- #define MT_FREE 7
- #define MT_MAP 8
-
- #define NORMAL 0
- #define UPPER 1
-
- #define USAGE "MAP 2.0, memory map utility, Sulyok Peter (C) 1992,1994.\n" \
- "Usage: MAP [-option ...]\n" \
- "Options:\n" \
- " -n list of programs in normal memory (default)\n" \
- " -u list of programs in normal and upper memory\n" \
- " -f full list of memory blocks\n" \
- " -d list of device drivers\n" \
- " -x XMS report\n" \
- " -e EMS report\n" \
- " -h,? this text"
-
- // Types --------------------------------------------------------------------
-
- // Structure of device driver header.
- typedef struct device_header {
- struct device_header *next;
- ushort attr;
- ushort strategy_rutin;
- ushort interrupt_rutin;
- uchar name[8];
- } DEVICE_HEADER;
-
- // Structure of device driver information.
- typedef struct {
- struct device_header *addr;
- uchar devname[9];
- uchar progname[9];
- ushort attr;
- uchar drive_num;
- uchar drives[MAX_DRIVE];
- } DINFO;
-
- // Structure of DOS DPB.
- typedef struct dpb {
- uchar drive_num;
- uchar unit_number;
- ushort bytes_in_sector;
- uchar lsec_num;
- uchar log_base;
- ushort reserved_num;
- uchar FAT_num;
- ushort rootentry_num;
- ushort first_sector;
- ushort largest_cluster;
- ushort sectors_in_FAT;
- ushort root_firstsector;
- DEVICE_HEADER *device_addr;
- uchar media_desc;
- uchar block_flag;
- struct dpb *next_dpb;
- } DPB;
-
- // Internal structure of DOS DATA blocks.
- typedef struct {
- uchar type;
- ushort start;
- ushort size;
- uchar unused[3];
- uchar name[8];
- } SD_HEADER;
-
- // Stucture of MCB header.
- typedef struct {
- uchar type;
- ushort owner;
- ushort size;
- uchar unused[3];
- uchar name[8];
- } MCB;
-
- // Structure of programs, device drivers, memory blocks information.
- typedef struct {
- uchar type;
- ushort seg;
- ushort owner;
- ushort environment;
- uchar name[10];
- ulong size;
- uchar vecnum;
- uchar vectors[MAX_VEC];
- } MINFO;
-
- // Structure of allocated EMS handles.
- typedef struct {
- ushort handle;
- ushort pages;
- } EMS_HANDLE;
-
- // Structure of allocated XMS handles.
- typedef struct {
- ushort handle;
- ulong size;
- ushort locks;
- } XMS_HANDLE;
-
- // Local variables ----------------------------------------------------------
- static uchar copyright[]=
- "Sulyok Péter (C) 1992,1994.";
-
- static MCB *first_mcb=NULL;
- static MINFO mlist[MAX_ITEM];
- static ushort mlistnum=0;
- static DEVICE_HEADER *first_dev=NULL;
- static DPB *first_dpb=NULL;
- static DINFO dlist[MAX_ITEM];
- static ushort dlistnum=0;
- static uchar *typenames[]=
- {
- " ",
- "system code ",
- "system data ",
- "program ",
- "device driver",
- "environment ",
- "data area ",
- "free ",
- };
-
- static uchar ems_installed=FALSE;
- static uchar ems_name[]="EMMXXXX0";
- static ushort ems_frame=0;
- static uchar ems_vermajor=0;
- static uchar ems_verminor=0;
- static ulong ems_size=0L;
- static ulong ems_free=0L;
- static ushort ems_totalhandle=0;
- static ushort ems_freehandle=0;
- static ushort ems_usehandle=0;
- static EMS_HANDLE ems_handles[MAX_HANDLE];
-
- static uchar xms_installed=FALSE;
- static void far (*xms_drv)(void);
- static ulong xms_free=0L;
- static ulong xms_largest=0L;
- static uchar xms_vermajor=0;
- static uchar xms_verminor=0;
- static uchar xms_hma=0;
- static uchar xms_a20=0;
- static XMS_HANDLE xms_handles[MAX_HANDLE];
- static ushort xms_usehandle=0;
- static ushort xms_freehandle=0;
-
- static uchar upper_installed=FALSE;
- static ulong upper_free=0L;
- static ulong upper_large=0L;
- static ushort upper_index=0;
-
- // Local functions ----------------------------------------------------------
- static void check_ems(void);
- static void check_xms(void);
- static void check_upper(void);
- static void check_memory(void);
- static uchar get_upperlink(void);
- static int set_upperlink(uchar);
- static void search_vectors(MINFO *);
- static void search_sd(MCB *);
- static void register_mcb(MCB *);
- static int is_psp(MCB *);
- static ushort env_seg(MCB *);
- static void make_mcb_list(void);
- static void make_dev_list(void);
- static void normal_list(uchar type);
- static void full_list(void);
- static void device_list(void);
- static void ems_list(void);
- static void xms_list(void);
-
- // --------------------------------------------------------------------------
- // Name: check_ems
- // Input: -
- // Output: -
- // Notes: Checks EMS memory and gets EMS parameters.
- // --------------------------------------------------------------------------
- static void check_ems(void)
- {
- void far *int67;
-
- int67=(void *)getvect(0x67);
- if (int67 == NULL)
- return;
-
- asm push ds
- asm push si
- asm push di
- asm les di,int67
- asm mov di,10
- asm lea si,ems_name
- asm mov cx,8
- asm cld
- asm repe cmpsb
- asm pop di
- asm pop si
- asm pop ds
- asm jz _found
- return;
-
- _found:
- ems_installed=TRUE;
-
- asm mov ah,41h
- asm int 67h
- asm or ah,ah
- asm jnz _error
- asm mov ems_frame,bx
-
- asm mov ah,46h
- asm int 67h
- asm or ah,ah
- asm jnz _error
- asm mov bl,al
- asm and al,0fh
- asm and bl,0f0h
- asm mov cl,4
- asm shr bl,cl
- asm mov ems_vermajor,bl
- asm mov ems_verminor,al
-
- asm mov ah,42h
- asm int 67h
- asm or ah,ah
- asm jnz _error
- asm mov word ptr ems_size,dx
- asm mov word ptr ems_size[2],0
- asm mov word ptr ems_free,bx
- asm mov word ptr ems_free[2],0
- ems_size*=16384L;
- ems_free*=16384L;
-
- asm push di
- _ES=FP_SEG(&ems_handles);
- _DI=FP_OFF(&ems_handles);
- asm mov ah,4Dh
- asm int 67h
- asm pop di
- asm or ah,ah
- asm jnz _error
- asm mov ems_usehandle,bx
-
- if (ems_vermajor >= 4) {
- asm mov ax,5402h
- asm int 67h
- asm or ah,ah
- asm jnz _error
- asm mov ems_totalhandle,bx
- } else {
- ems_totalhandle=ems_usehandle;
- }
-
- ems_freehandle=ems_totalhandle - ems_usehandle;
- return;
-
- _error:
- puts("EMS INTERNAL ERROR.");
- exit(1);
- }
-
- // --------------------------------------------------------------------------
- // Name: check_xms
- // Input: -
- // Output: -
- // Notes: Checks XMS memory and gets XMS parameters.
- // --------------------------------------------------------------------------
- static void check_xms(void)
- {
- asm mov ax,4300h
- asm int 2fh
- asm cmp al,80h
- asm je _found
- return;
-
- _found:
- xms_installed=TRUE;
-
- asm mov ax,4310h
- asm int 2fh
- asm mov word ptr xms_drv,bx
- asm mov word ptr xms_drv[2],es
-
- asm mov ah,0
- (*xms_drv)();
- asm mov xms_vermajor,ah
- asm mov xms_verminor,al
- asm mov xms_hma,dl
-
- asm mov ah,8
- (*xms_drv)();
- asm mov word ptr xms_free,ax
- asm mov word ptr xms_free[2],0
- asm mov word ptr xms_largest,dx
- asm mov word ptr xms_largest[2],0
- xms_free*=1024L;
- xms_largest*=1024L;
-
- asm mov ah,7
- (*xms_drv)();
- asm or bl,bl
- asm jnz _error
- asm mov xms_a20,al
- return;
-
- _error:
- puts("XMS INTERNAL ERROR.");
- exit(1);
- }
-
- // --------------------------------------------------------------------------
- // Name: get_upperlink
- // Input: -
- // Output: uchar 0 separated upper and normal blocks
- // 1 linked upper and normal blocks
- // Notes: Checks the connection of normal and upper memory blocks.
- // --------------------------------------------------------------------------
- static uchar get_upperlink(void)
- {
- asm mov ax,5802h
- asm int 21h
- return(_AL);
- }
-
- // --------------------------------------------------------------------------
- // Name: set_upperlink
- // Input: uchar link 0 separate it
- // 1 link it
- // Output: int 1 successful
- // 0 there is no upper memory
- // -1 system memory is trashed
- // Notes: Set the connection between upper and normal memory
- // blocks.
- // --------------------------------------------------------------------------
- static int set_upperlink(uchar link)
- {
- asm mov ax,5803h
- asm xor bh,bh
- asm mov bl,link
- asm int 21h
- asm jc _noumb
-
- return(1);
-
- _noumb:
- asm cmp ax,1
- asm jne _trash
- return(0);
-
- _trash:
- return(-1);
- }
-
- // --------------------------------------------------------------------------
- // Name: check_upper
- // Input: -
- // Output: -
- // Notes: Checks upper memory.
- // --------------------------------------------------------------------------
- static void check_upper(void)
- {
- uchar origlink;
-
- origlink=get_upperlink();
- switch(set_upperlink(1)) {
- case 1:
- upper_installed=TRUE;
- break;
-
- case 0:
- upper_installed=FALSE;
- break;
-
- case -1:
- puts("SYSTEM MEMORY TRASHED!");
- exit(1);
- break;
- }
- set_upperlink(origlink);
- }
-
- // --------------------------------------------------------------------------
- // Name: check_memory
- // Input: -
- // Output: -
- // Notes: Checks EMS, XMS, upper memory.
- // --------------------------------------------------------------------------
- static void check_memory(void)
- {
- check_ems();
- check_xms();
- check_upper();
- }
-
- // --------------------------------------------------------------------------
- // Name: is_psp
- // Input: MCB *mcb address of the MSC structure
- // Output: int TRUE it is a program
- // FALSE it is a simple MCB block
- // Notes: Checks the PSP of given MCB block.
- // --------------------------------------------------------------------------
- static int is_psp(MCB *mcb)
- {
- asm les bx,mcb
- asm mov ax,es
- asm inc ax
- asm mov es,ax
- asm mov ax,TRUE
- asm cmp word ptr es:[bx],20CDh
- asm je __exit
- asm mov ax,FALSE
-
- __exit:
- return(_AX);
- }
-
- // --------------------------------------------------------------------------
- // Name: env_seg
- // Input: MCB *mcb address of MCB block
- // Output: ushort segment of enviroment
- // Notes: Returns the segment of the given MCB block.
- // --------------------------------------------------------------------------
- static ushort env_seg(MCB *mcb)
- {
- MCB *env;
-
- asm les bx,mcb
- asm mov ax,es
- asm inc ax
- asm mov es,ax
- asm mov bx,ax
- asm mov ax,es:[2Ch]
- asm dec ax
- asm mov es,ax
- asm inc ax
- asm cmp es:[1],bx
- asm je __exit
- asm mov ax,0
-
- __exit:
- return(_AX);
- }
-
- // --------------------------------------------------------------------------
- // Name: search_vectors
- // Input: MINFO *m address of a memory block
- // Output: -
- // Notes: Searches interrupt vectors of the given memory block.
- // --------------------------------------------------------------------------
- static void search_vectors(MINFO *m)
- {
- ushort i;
- ulong begin, end, iv;
- uchar far *ivp;
-
- begin=(ulong)(m->seg + 1) << 4;
- end=begin + m->size;
- for(i=0; i<256; i++) {
- memcpy(&ivp, MK_FP(0, i*4), 4);
- iv=((ulong)(FP_SEG(ivp) + 1) << 4) + (ulong)FP_OFF(ivp);
- if ((iv > begin) && (iv < end) && (m->vecnum < MAX_VEC))
- m->vectors[m->vecnum++]=(uchar)i;
- }
- }
-
- // --------------------------------------------------------------------------
- // Name: search_sd
- // Input: MCB *mcb address of MCB block
- // Output: -
- // Notes: Searches the internal parts of a DOS data block.
- // --------------------------------------------------------------------------
- static void search_sd(MCB *mcb)
- {
- ushort begin, end;
- SD_HEADER *sd;
-
- sd=MK_FP(FP_SEG(mcb) + 1, 0);
- begin=FP_SEG(mcb);
- end=FP_SEG(mcb) + mcb->size;
- while((FP_SEG(sd) > begin) &&
- (FP_SEG(sd) < end) &&
- (mlistnum < MAX_ITEM)) {
- mlistnum++;
- mlist[mlistnum].seg=sd->start;
- mlist[mlistnum].size=(ulong)sd->size << 4;
- switch(sd->type) {
- case 'D':
- case 'I':
- mlist[mlistnum].name[0]=' ';
- strncpy(&mlist[mlistnum].name[1], sd->name, 8);
- strupr(mlist[mlistnum].name);
- mlist[mlistnum].type=MT_DEVICE;
- break;
-
- case 'F':
- strcpy(mlist[mlistnum].name, " FILES");
- mlist[mlistnum].type=MT_DATA;
- break;
-
- case 'X':
- strcpy(mlist[mlistnum].name, " FCBS");
- mlist[mlistnum].type=MT_DATA;
- break;
-
- case 'C':
- case 'B':
- strcpy(mlist[mlistnum].name, " BUFFERS");
- mlist[mlistnum].type=MT_DATA;
- break;
-
- case 'L':
- strcpy(mlist[mlistnum].name, " LASTDRV");
- mlist[mlistnum].type=MT_DATA;
- break;
-
- case 'S':
- strcpy(mlist[mlistnum].name, " STACKS");
- mlist[mlistnum].type=MT_DATA;
- break;
-
- default:
- strcpy(mlist[mlistnum].name, " ??????");
- mlist[mlistnum].type=MT_DATA;
- break;
- }
- sd=MK_FP(sd->start + sd->size, 0);
- }
- }
-
- // --------------------------------------------------------------------------
- // Name: check_name
- // Input: uchar *name name of MCB or device driver
- // Output: -
- // Notes: Filters name of MCBs and device drivers.
- // --------------------------------------------------------------------------
- void check_name(uchar *name)
- {
- ushort i;
-
- for(i=0; name[i]; i++)
- if ( name[i] < ' ' ) {
- name[i] = '\0';
- break;
- } // if
- }
-
- // --------------------------------------------------------------------------
- // Name: register_mcb
- // Input: MCB *mcb address of MCB block
- // Output: -
- // Notes: Registers parameters of the given MCB block.
- // --------------------------------------------------------------------------
- static void register_mcb(MCB *mcb)
- {
- mlist[mlistnum].seg=FP_SEG(mcb);
- mlist[mlistnum].owner=mcb->owner;
- mlist[mlistnum].size=(ulong)mcb->size << 4;
-
- if (mlist[mlistnum].seg <= 0x9FFF) {
- if (is_psp(mcb)) {
- strncpy(mlist[mlistnum].name, mcb->name, 8);
- check_name(mlist[mlistnum].name);
- strupr(mlist[mlistnum].name);
- mlist[mlistnum].environment=env_seg(mcb);
- mlist[mlistnum].type=MT_PROGRAM;
- }
- if (!mcb->owner) {
- mlist[mlistnum].type=MT_FREE;
- } else if (mcb->owner <= 0x0008) {
- strcpy(mlist[mlistnum].name, "DOS");
- if (!strncmp(mcb->name, "SD", 2)) {
- mlist[mlistnum].type=MT_SYSDATA;
- search_sd(mcb);
- } else if (!strncmp(mcb->name, "SC", 2)) {
- mlist[mlistnum].type=MT_SYSCODE;
- }
- else
- mlist[mlistnum].type=MT_SYSCODE;
- }
-
- } else {
- if (!mcb->owner) {
- mlist[mlistnum].type=MT_FREE;
- } else if (mcb->owner <= 0x0008) {
- strcpy(mlist[mlistnum].name, "DOS");
- if (!strncmp(mcb->name, "SD", 2)) {
- mlist[mlistnum].type=MT_SYSDATA;
- search_sd(mcb);
- } else if (!strncmp(mcb->name, "SC", 2)) {
- mlist[mlistnum].type=MT_SYSCODE;
- }
- } else if (mcb->owner > 0x0008) {
- mlist[mlistnum].environment=env_seg(mcb);
- mlist[mlistnum].type=MT_PROGRAM;
- strncpy(mlist[mlistnum].name, mcb->name, 8);
- strupr(mlist[mlistnum].name);
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // Name: make_mcb_list
- // Input: -
- // Output: -
- // Notes: Makes the list of MCBs.
- // --------------------------------------------------------------------------
- static void make_mcb_list(void)
- {
- ushort i, j;
- MCB *cur_mcb;
- uchar origlink;
-
- memset(mlist, 0, sizeof(mlist));
- check_memory();
-
- asm mov ah,52h
- asm int 21h
- asm mov ax,es:[bx-2]
- asm mov word ptr first_mcb[2],ax
- asm mov word ptr first_mcb,0
-
- if (upper_installed) {
- origlink=get_upperlink();
- set_upperlink(1);
- }
-
- cur_mcb=(MCB *)MK_FP(first_mcb, 0);
- while((mlistnum < MAX_ITEM) && (cur_mcb->type != 'Z')) {
- register_mcb(cur_mcb);
- cur_mcb=(MCB *)MK_FP(FP_SEG(cur_mcb) + cur_mcb->size + 1, 0);
- ++mlistnum;
- }
-
- register_mcb(cur_mcb);
- cur_mcb=(MCB *)MK_FP(FP_SEG(cur_mcb) + cur_mcb->size + 1, 0);
- ++mlistnum;
-
- if (upper_installed)
- set_upperlink(origlink);
-
- for(i=0; i<mlistnum; i++)
- if ( (mlist[i].seg >= 0x9000) && (mlist[i].seg <= 0xB000) &&
- (mlist[i].type == MT_SYSCODE) ) {
- upper_index=i;
- break;
- }
-
- for(i=upper_index; i<mlistnum; i++)
- if (mlist[i].type == MT_FREE) {
- upper_free+=mlist[i].size;
- if (mlist[i].size > upper_large)
- upper_large=mlist[i].size;
- }
-
- for(i=0; i<mlistnum; i++) {
- if (mlist[i].type == MT_PROGRAM)
- for(j=0; j<mlistnum; j++)
- if ((mlist[i].seg != mlist[j].seg) &&
- (mlist[j].owner == mlist[i].seg+1)) {
- strcpy(mlist[j].name, mlist[i].name);
- mlist[j].type=(mlist[i].environment == mlist[j].seg+1) ? MT_ENV : MT_DATA;
- }
- if (mlist[i].type != MT_SYSDATA)
- search_vectors(&mlist[i]);
- }
-
- for(i=0; i<mlistnum; i++)
- if (mlist[i].seg+1 == _psp) {
- mlist[i+1].size+=mlist[i].size + 16;
- mlist[i].type=MT_MAP;
- for(j=0; j<mlistnum; j++)
- if (mlist[j].seg+1 == mlist[i].environment) {
- if (j == i-1) {
- mlist[j].type=MT_MAP;
- } else {
- mlist[j].type=MT_FREE;
- mlist[j].name[0]='\0';
- }
- break;
- }
- break;
- }
- }
-
- // --------------------------------------------------------------------------
- // Name: make_dev_list
- // Input: -
- // Output: -
- // Notes: Makes list of device drivers.
- // --------------------------------------------------------------------------
- static void make_dev_list(void)
- {
- ushort i, j;
- DEVICE_HEADER *cur_dev;
- DPB *cur_dpb;
-
- memset(dlist, 0, sizeof(dlist));
- make_mcb_list();
-
- asm mov ah,52h
- asm int 21h
- asm add bx,22h
- asm mov word ptr first_dev[2],es
- asm mov word ptr first_dev,bx
-
- cur_dev=first_dev;
- while((FP_OFF(cur_dev) != 0xFFFF) &&
- (dlistnum < MAX_ITEM)) {
- dlist[dlistnum].addr=cur_dev;
- dlist[dlistnum].attr=cur_dev->attr;
- strncpy(dlist[dlistnum].devname, cur_dev->name, 8);
- check_name(dlist[dlistnum].devname);
- strupr(dlist[dlistnum].devname);
- cur_dev=cur_dev->next;
- ++dlistnum;
- }
-
- for(i=0; i<dlistnum; i++)
- for(j=0; j<mlistnum; j++)
- if (mlist[j].seg == FP_SEG(dlist[i].addr))
- strcpy(dlist[i].progname, (mlist[j].name[0] == ' ') ?
- &mlist[j].name[1] : mlist[j].name);
-
- asm mov ah,52h
- asm int 21h
- asm les bx,es:[bx]
- asm mov word ptr first_dpb[2],es
- asm mov word ptr first_dpb,bx
-
- cur_dpb=first_dpb;
- while(FP_OFF(cur_dpb) != 0xFFFF) {
- for(i=0; i<dlistnum; i++)
- if (dlist[i].addr == cur_dpb->device_addr) {
- dlist[i].drives[dlist[i].drive_num++]=cur_dpb->drive_num+'A';
- break;
- }
- cur_dpb=cur_dpb->next_dpb;
- }
-
- for(i=0; i<dlistnum; i++) {
- if ((dlist[i].attr & 0x8000) == 0)
- dlist[i].devname[0]='\0';
- if (dlist[i].drive_num) {
- if (dlist[i].drive_num == 1)
- sprintf(dlist[i].devname, "%c:", dlist[i].drives[0]);
- else
- sprintf(dlist[i].devname, "%c: - %c:", dlist[i].drives[0],
- dlist[i].drives[dlist[i].drive_num-1]);
- }
- }
- }
-
- // --------------------------------------------------------------------------
- // Name: normal_list
- // Input: uchar type type of list
- // Output: -
- // Notes: Displays the normal list of programs.
- // --------------------------------------------------------------------------
- static void normal_list(uchar type)
- {
- ushort i, num;
-
- make_mcb_list();
-
- puts("┌───────────────────────────────────────────┐");
- puts("│ mcb size name type │");
- puts("├──────┬────────┬───────────┬───────────────┤");
- num=(upper_installed && (type == NORMAL)) ? upper_index : mlistnum;
- for(i=0; i<num; i++)
- if ((mlist[i].type == MT_SYSCODE) ||
- (mlist[i].type == MT_SYSDATA) ||
- (mlist[i].type == MT_FREE) ||
- (mlist[i].type == MT_PROGRAM) ||
- (mlist[i].type == MT_DEVICE))
- printf("│ %04x │ %6lu │ %-9s │ %-13s │\n",
- mlist[i].seg, mlist[i].size, mlist[i].name,
- typenames[mlist[i].type]);
-
- if (!ems_installed && !xms_installed && !upper_installed) {
- puts("└──────┴────────┴───────────┴───────────────┘");
- return;
- }
-
- puts("├──────┴────────┴───────────┴───────────────┤");
-
- if (ems_installed)
- printf("│ %8lu bytes free EMS memory │\n", ems_free);
-
- if (xms_installed)
- printf("│ %8lu bytes free XMS memory │\n", xms_free);
-
- if (upper_installed)
- printf("│ %8lu bytes free upper memory │\n", upper_free);
-
- puts("└───────────────────────────────────────────┘");
- }
-
- // --------------------------------------------------------------------------
- // Name: full_list
- // Input: -
- // Output: -
- // Notes: Displays full list of memory blocks.
- // --------------------------------------------------------------------------
- static void full_list(void)
- {
- ushort i, j, pos;
- uchar line[81];
-
- make_mcb_list();
-
- puts("┌────────────────────────────────────────────────────────────────────────┐");
- puts("│ mcb size name type interrupt vectors │");
- puts("├──────┬────────┬───────────┬───────────────┬────────────────────────────┤");
- for(i=0; i<mlistnum; i++)
- if (mlist[i].type != MT_MAP) {
- sprintf(line, "│ %04x │ %6lu │ %-9s │ %-4s │ │",
- mlist[i].seg, mlist[i].size, mlist[i].name,
- typenames[mlist[i].type]);
- for(j=1, pos=46; j<=mlist[i].vecnum; j++) {
- sprintf(&line[pos], "%02x", (int)mlist[i].vectors[j-1]);
- line[pos+2]=' ';
- if (!(j % 9) && ((j+1) <= mlist[i].vecnum)) {
- puts(line);
- strcpy(line, "│ │ │ │ │ │");
- pos=46;
- } else {
- pos+=3;
- }
- }
- puts(line);
- }
-
- puts("└──────┴────────┴───────────┴───────────────┴────────────────────────────┘");
- }
-
- // --------------------------------------------------------------------------
- // Name: device_list
- // Input: -
- // Output: -
- // Notes: Display the list of device drivers.
- // --------------------------------------------------------------------------
- static void device_list(void)
- {
- ushort i, num;
-
- make_dev_list();
-
- puts("┌────────────────────────────────────────┐");
- puts("│ address attr name program │");
- puts("├───────────┬──────┬──────────┬──────────┤");
- // XXXX:XXXX XXXX XXXXXXXX XXXXXXXX
- for(i=0; i<dlistnum; i++)
- printf("│ %Fp │ %04x │ %-8s │ %-8s │\n",
- dlist[i].addr, dlist[i].attr, dlist[i].devname,
- dlist[i].progname);
-
- puts("└───────────┴──────┴──────────┴──────────┘");
- }
-
- // --------------------------------------------------------------------------
- // Name: ems_list
- // Input: -
- // Output: -
- // Notes: Displays the EMS report.
- // --------------------------------------------------------------------------
- static void ems_list(void)
- {
- ushort i;
- uchar *line, numstr[20];
- uchar handlename[9];
-
- check_ems();
-
- puts("┌─────────────────────────────────────┐");
-
- if (!ems_installed) {
- puts("│ EMS driver not installed in system. │");
- } else {
- line="│ EMS driver version │";
- sprintf(numstr, "%1i.%1i", (int)ems_vermajor, (int)ems_verminor);
- strncpy(&line[22], numstr, strlen(numstr));
- puts(line);
-
- line="│ EMS page frame │";
- sprintf(numstr, "%04X", ems_frame);
- strncpy(&line[22], numstr, strlen(numstr));
- puts(line);
-
- line="│ Total EMS memory │";
- sprintf(numstr, "%lu bytes", ems_size);
- strncpy(&line[22], numstr, strlen(numstr));
- puts(line);
-
- line="│ Free EMS memory │";
- sprintf(numstr, "%lu bytes", ems_free);
- strncpy(&line[22], numstr, strlen(numstr));
- puts(line);
-
- line="│ Total handles │";
- sprintf(numstr, "%u", ems_totalhandle);
- strncpy(&line[22], numstr, strlen(numstr));
- puts(line);
-
- line="│ Free handles │";
- sprintf(numstr, "%u", ems_freehandle);
- strncpy(&line[22], numstr, strlen(numstr));
- puts(line);
-
- puts("│ │");
- puts("│ Handle Pages Size Name │");
- puts("│ ─────────────────────────────────── │");
- for(i=0; i<ems_usehandle; i++) {
- memset(handlename, 0, sizeof(handlename));
- if (ems_vermajor >= 4) {
- if (ems_handles[i].handle == 0) {
- strcpy(handlename, "SYSTEM");
- } else {
- asm push di
- _DX=ems_handles[i].handle;
- _ES=FP_SEG(&handlename);
- _DI=FP_OFF(&handlename);
- asm mov ax,5300h
- asm int 67h
- asm pop di
- }
- strupr(handlename);
- }
- printf("│ %-7u %-6u %-9lu %-9s │\n",
- ems_handles[i].handle, ems_handles[i].pages,
- (ulong)ems_handles[i].pages * 16384L, handlename);
- }
-
- }
- puts("└─────────────────────────────────────┘");
- }
-
- // --------------------------------------------------------------------------
- // Name: xms_list
- // Input: -
- // Output: -
- // Notes: Displays the XMS report.
- // --------------------------------------------------------------------------
- static void xms_list(void)
- {
- ushort i;
- uchar *line, numstr[20];
-
- make_mcb_list();
-
- if (xms_installed) {
- printf("Testing XMS memory ...");
- memset(xms_handles, 0, sizeof(xms_handles));
- xms_usehandle=0;
- for(i=0; i<65535; i++) {
- asm mov ah,0Eh
- _DX=i;
- (*xms_drv)();
- asm or ax,ax
- asm jnz _found
- continue;
-
- _found:
- asm mov byte ptr xms_freehandle,bl
- if (xms_usehandle < MAX_HANDLE) {
- asm push di
- _ES=FP_SEG(&xms_handles);
- _DI=FP_OFF(&xms_handles);
- asm mov ax,xms_usehandle // xms_handles[xms_usehandle].handle=i;
- asm mov cl,3
- asm shl ax,cl
- asm add di,ax
- asm mov ax,i
- asm mov es:[di],ax
- asm mov es:[di+2],dx // xms_handles[xms_usehandle].size=_DX;
- asm mov es:[di+6],bh // xms_handles[xms_usehandle].locks=_BH;
- asm pop di
- xms_handles[xms_usehandle].size*=1024L;
- xms_usehandle++;
- }
- }
- printf("\r");
- }
-
- puts("┌────────────────────────────────────────┐");
-
- if (!xms_installed) {
- puts("│ XMS driver not installed in system. │");
- } else {
- line="│ XMS driver version │";
- sprintf(numstr, "%i.%i", (ushort)xms_vermajor, (ushort)xms_verminor);
- strncpy(&line[26], numstr, strlen(numstr));
- puts(line);
-
- line="│ HMA state │";
- sprintf(numstr, "%s", (xms_hma) ? "exists" : "not exists");
- strncpy(&line[26], numstr, strlen(numstr));
- puts(line);
-
- line="│ A20 line state │";
- sprintf(numstr, "%s", (xms_a20) ? "enabled" : "disabled");
- strncpy(&line[26], numstr, strlen(numstr));
- puts(line);
-
- line="│ Free XMS memory │";
- sprintf(numstr, "%lu bytes", xms_free);
- strncpy(&line[26], numstr, strlen(numstr));
- puts(line);
-
- line="│ Largest free XMS block │";
- sprintf(numstr, "%lu bytes", xms_largest);
- strncpy(&line[26], numstr, strlen(numstr));
- puts(line);
-
- line="│ Free handles │";
- sprintf(numstr, "%u", xms_freehandle);
- strncpy(&line[26], numstr, strlen(numstr));
- puts(line);
-
- if (xms_usehandle) {
- puts("│ │");
- puts("│ Block Handle Size Locks │");
- puts("│ ────────────────────────────────────── │");
- for(i=0; i<xms_usehandle; i++)
- printf("│ %-6u %-7u %-9lu %-12u │\n",
- i, xms_handles[i].handle, xms_handles[i].size,
- xms_handles[i].locks);
- }
-
- puts("│ │");
- if (upper_installed) {
- line="│ Free upper memory │";
- sprintf(numstr, "%lu bytes", upper_free);
- strncpy(&line[26], numstr, strlen(numstr));
- puts(line);
- line="│ Largest upper block │";
- sprintf(numstr, "%lu bytes", upper_large);
- strncpy(&line[26], numstr, strlen(numstr));
- puts(line);
- } else {
- puts("│ Upper memory not available │");
- }
- }
-
- puts("└────────────────────────────────────────┘");
- }
-
- // Main ---------------------------------------------------------------------
- int main(int argc, char *argv[])
- {
- ushort i;
-
- if ( (_osmajor != 5) && (_osmajor != 6 ) ) {
- puts("This program runs under DOS 5.x or 6.x versions.");
- return 1;
- }
-
- if (argc > 1) {
- for(i=1; i<argc; i++) {
- if ((argv[i][0] == '-') || (argv[i][0] == '/'))
- switch( argv[i][1] ) {
- case 'n':
- case 'N':
- normal_list(NORMAL);
- break;
-
- case 'u':
- case 'U':
- normal_list(UPPER);
- break;
-
- case 'f':
- case 'F':
- full_list();
- break;
-
- case 'd':
- case 'D':
- device_list();
- break;
-
- case 'e':
- case 'E':
- ems_list();
- break;
-
- case 'x':
- case 'X':
- xms_list();
- break;
-
- case 'h':
- case 'H':
- case '?':
- puts(USAGE);
- return 0;
-
- default:
- printf("Invalid option %s (use -h for help).\n", argv[i]);
- return 1;
- }
-
- else {
- printf("Invalid option %s (use -h for help).\n", argv[i]);
- return 1;
- }
- }
- } else {
- normal_list(NORMAL);
- }
-
- return 0;
- }
-
- // End ----------------------------------------------------------------------
-